package com.cloudkinto.service.orderqoo.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.common.DateFormater;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.OkHttpUtils;
import com.cloudkinto.common.utils.OrderCodeUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.orderoutput.vo.OrderOutputAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputPackageAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputProductAddReq;
import com.cloudkinto.service.orderqoo.OrderQoo10Service;
import com.cloudkinto.service.orderqoo.vo.*;
import com.cloudkinto.service.product.ProductInfoService;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.shop.ShopService;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author zhangyy
 * @since 2020-08-13
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class OrderQoo10ServiceImpl extends ServiceImpl<OrderQoo10Dao, OrderQoo10Do> implements OrderQoo10Service {
    @Autowired
    private OrderQoo10Dao dao;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderOutputDao orderOutputDao;
    @Autowired
    private OrderOutputPackageDao orderOutputPackageDao;
    @Autowired
    private OrderOutputProductDao orderOutputProductDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private ShopService shopService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private OrderOutputService outputService;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private JpRegionService mRegionService;
    @Autowired
    private StockRecordDao stockRecordDao;
    @Autowired
    private ShipPriceService shipPriceService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    private Logger logger = Logger.getLogger("OrderQoo10ServiceImpl");
    @Autowired
    private ProductInfoService productInfoService;

    @Override
    public SingleResult addInit(Long userId, Long companyId) {
        Map result = new HashMap();

        List<Map> ShippingStatList = new ArrayList<>();
        Map map = new HashMap();
        map.put("id", 1);
        map.put("value", "支払待ち");
        ShippingStatList.add(map);
        map = new HashMap();
        map.put("id", 2);
        map.put("value", "支払済み");
        ShippingStatList.add(map);
        map = new HashMap();
        map.put("id", 3);
        map.put("value", "配送確認");
        ShippingStatList.add(map);
        map = new HashMap();
        map.put("id", 4);
        map.put("value", "配送中");
        ShippingStatList.add(map);
        map = new HashMap();
        map.put("id", 5);
        map.put("value", "配送完了");
        ShippingStatList.add(map);

        result.put("ShippingStatList", ShippingStatList);


        List<Map> searchConditionList = new ArrayList<>();
        map = new HashMap();
        map.put("id", 1);
        map.put("value", "注文日");
        searchConditionList.add(map);
        map = new HashMap();
        map.put("id", 2);
        map.put("value", "決済完了日");
        searchConditionList.add(map);
        map = new HashMap();
        map.put("id", 3);
        map.put("value", "配送日");
        searchConditionList.add(map);
        map = new HashMap();
        map.put("id", 4);
        map.put("value", "配送完了日");
        searchConditionList.add(map);

        result.put("searchConditionList", searchConditionList);

        result.put("shopList", shopService.selectShopListInit(userId, companyId));

        return SingleResult.success(result);
    }

    @Override
    public void autoRefreshOrder() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.isNotNull("qooten_id");
        wrapper.isNotNull("qooten_pwd");
        wrapper.isNotNull("qooten_key");
        List<ShopDo> shopDos = shopDao.selectList(wrapper);
        for (ShopDo shopDo : shopDos) {
            String key = getQoo10Token(shopDo.getId());

            for (int i = 0; i < 6; i++) {
                QooDownloadReq req = new QooDownloadReq();
                if (0 < i && i < 3) continue;
                req.setShippingStatus(i + "");
                req.setSearchCondition(1 + "");
                req.setShopId(shopDo.getId());
                req.setStartDate(TimeUtils.parseDate(TimeUtils.getCurrentDateFormat(-5)));
                req.setEndDate(new Date());
                downloadQooOrders(key, req, 168L, shopDo.getCompanyId());
            }
            for (int i = 0; i < 16; i++) {
                downloadQooOrdersClaim(key, (i + 1) + "", TimeUtils.parseDate(TimeUtils.getCurrentDateFormat(-5)), new Date());
            }
        }
    }

    private void downloadQooOrdersClaim(String key, String s, Date startDate1, Date endDate1) {
        String startDate = DateFormater.formatSecond(startDate1);
        String endDate = DateFormater.formatSecond(endDate1);
        StringBuilder url = new StringBuilder(GlobalConstants.QOO_BASE_URL);
        url.append("?v=1.0&").append("&returnType=json&method=ShippingBasic.GetClaimInfo_V3");
        if (StringUtils.isNotBlank(s)) {
            url.append("&ClaimStat=" + s);
        }
        url.append("&search_condition=" + 2);

        if (StringUtils.isNotBlank(key)) {
            url.append("&key=" + key);
        }
        if (StringUtils.isNotBlank(startDate)) {
            url.append("&search_Sdate=" + startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            url.append("&search_Edate=" + endDate);
        }
        JSONObject listObject = null;

        String date = OkHttpUtils.okHttpRequestGet(url.toString());
        List<OrderQoo10ClaimRes> orderQoo10Dos = JSON.parseArray(JSON.toJSONString(JSONObject.parseObject(date).get("ResultObject")), OrderQoo10ClaimRes.class);
        List<String> cancelSendOrderNumber = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderQoo10Dos)) {
            for (OrderQoo10ClaimRes orderQoo10res : orderQoo10Dos) {
                LambdaQueryWrapper<OrderQoo10Do> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(OrderQoo10Do::getOrderNo, orderQoo10res.getOrderNo());
                int count = dao.selectCount(wrapper);
                if (count > 0) {
                    OrderQoo10Do orderQoo10Do1 = null;
                    if (count == 1) {
                        orderQoo10Do1 = dao.selectOne(wrapper);
                    } else {
                        wrapper.orderByDesc(OrderQoo10Do::getId).last("limit 1");
                        orderQoo10Do1 = dao.selectOne(wrapper);

                    }
                    orderQoo10Do1.setShippingStatus(orderQoo10res.getClaimStatus());
                    orderQoo10Do1.setClaimStatus(orderQoo10res.getClaimStatus());
                    if (StringUtils.isNotBlank(orderQoo10res.getRequestDate()))
                        orderQoo10Do1.setCancelRequestDate(TimeUtils.parseDate(orderQoo10res.getRequestDate(), "yyyy-MM-dd HH:mm:ss"));
                    if (StringUtils.isNotBlank(orderQoo10res.getCancelRefundDate()))
                        orderQoo10Do1.setCancelDate(TimeUtils.parseDate(orderQoo10res.getCancelRefundDate(), "yyyy-MM-dd HH:mm:ss"));
                    updateById(orderQoo10Do1);
                    if (orderQoo10Do1.getShippingStatus() != null &&
                            orderQoo10Do1.getShippingStatus().contains("キャンセル")) {
                        cancelSendOrderNumber.add(orderQoo10Do1.getOrderNo() + "");
                    }
                }
                if (cancelSendOrderNumber.size() > 0)
                    outputService.cancelOrderByOrderId("qoo10", cancelSendOrderNumber);
            }
        }
    }

    @Override
    public void downloadQooOrders(QooDownloadReq req, Long userId, Long companyId) {
        downloadQooOrders(getQoo10Token(req.getShopId()), req, userId, companyId);
    }

    @Override
    public void downloadQooOrders(String key, QooDownloadReq req, Long userId, Long companyId) {
        if (companyId == null) {
            throw new BizException(SysConstant.Error_Company);
        }
        StringBuilder url = new StringBuilder(GlobalConstants.QOO_BASE_URL);

        String ShippingStat = req.getShippingStatus();
        String searchCondition = req.getSearchCondition();
        String startDate = DateFormater.formatSecond(req.getStartDate());
        String endDate = DateFormater.formatSecond(req.getEndDate());

//        Map<String,String> params = getParams(key, ShippingStat, startDate, endDate);
        url = new StringBuilder(GlobalConstants.QOO_BASE_URL);
        url.append("?v=1.0&").append("&returnType=json&method=ShippingBasic.GetShippingInfo_v2");
        if (StringUtils.isNotBlank(ShippingStat)) {
            url.append("&ShippingStat=" + ShippingStat);
        }
        if (StringUtils.isNotBlank(searchCondition)) {
            url.append("&search_condition=" + searchCondition);
        } else {
            url.append("&search_condition=" + 2);
        }
        if (StringUtils.isNotBlank(key)) {
            url.append("&key=" + key);
        }
        if (StringUtils.isNotBlank(startDate)) {
            url.append("&search_Sdate=" + startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            url.append("&search_Edate=" + endDate);
        }
        ShopDo shopDo = shopDao.selectById(req.getShopId());
        if (shopDo == null) return;
        String s = OkHttpUtils.okHttpRequestGet(url.toString());
        List<OrderQoo10Do> orderQoo10Dos = JSON.parseArray(JSON.toJSONString(JSONObject.parseObject(s).get("ResultObject")), OrderQoo10Do.class);
        List<Long> sendOrderNumber = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderQoo10Dos)) {
            orderQoo10Dos.forEach(orderQoo10Do -> {
                LambdaQueryWrapper<OrderQoo10Do> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(OrderQoo10Do::getOrderNo, orderQoo10Do.getOrderNo());
                int count = dao.selectCount(wrapper);
                if (count > 0) {
                    OrderQoo10Do orderQoo10Do1 = null;
                    if (count == 1) {
                        orderQoo10Do1 = dao.selectOne(wrapper);
                    } else {
                        wrapper.orderByDesc(OrderQoo10Do::getId).last("limit 1");
                        orderQoo10Do1 = dao.selectOne(wrapper);

                    }
                    BeanUtils.copyProperties(orderQoo10Do, orderQoo10Do1, new String[]{"id", "isSendOut", "isUploadExpress", "systemMemo"});
                    updateById(orderQoo10Do1);
                    if (orderQoo10Do.getShippingStatus().contains("2") || orderQoo10Do.getShippingStatus().contains("3")) {
                        if (orderQoo10Do.getIsSendOut() == null || orderQoo10Do.getIsSendOut() == 0)
                            sendOrderNumber.add(orderQoo10Do1.getId());
                    }
                    return;
                }
                orderQoo10Do.setShopId(req.getShopId());
                orderQoo10Do.setCompanyId(companyId);
                dao.insert(orderQoo10Do);
                if (orderQoo10Do.getShippingStatus().contains("2") || orderQoo10Do.getShippingStatus().contains("3")) {
                    if (orderQoo10Do.getIsSendOut() == null || orderQoo10Do.getIsSendOut() == 0)
                        sendOrderNumber.add(orderQoo10Do.getId());
                }
            });
        }
        QooSendOutReq req1 = new QooSendOutReq();
        req1.setIds(sendOrderNumber);
        logger.info("Qoo10自动发货开始");
        logger.info(JSONObject.toJSONString(req1));
        List<OrderOutputAddReq> orderOutputAddReqList = autoSendOut(req1, 1L, companyId);
        if (orderOutputAddReqList.size() > 0 && shopDo.getAutoSendOutFlag())
            sendOutMatch(orderOutputAddReqList, 1L, companyId);
        logger.info("Qoo10自动发货结束");
    }

    private List<OrderOutputAddReq> autoSendOut(QooSendOutReq req, long userId, Long companyId) {

        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        if (req.getIds() == null || req.getIds().size() < 1) return orderOutputAddReqList;
        List<OrderQoo10Do> orderQoo10DoList = dao.selectBatchIds(req.getIds());
        Map<Integer, List<OrderQoo10Do>> collectMap = orderQoo10DoList.stream().filter(orderQoo10Do -> orderQoo10Do.getPackNo() != null)
                .collect(Collectors.groupingBy(OrderQoo10Do::getPackNo));
        for (Map.Entry<Integer, List<OrderQoo10Do>> stringListEntry : collectMap.entrySet()) {
            Map<String, Object> result = sendOutOrder(stringListEntry, false, userId, companyId);
            if (result != null && result.get("orderOutputAddReq") != null) {
                orderOutputAddReqList.addAll((List) result.get("orderOutputAddReq"));
            }
        }

        List<OrderQoo10Do> orderQoo10Dos = this.baseMapper.selectBatchIds(req.getIds());
        orderQoo10Dos.forEach(orderQoo10Do -> {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, orderQoo10Do.getId(), userId, 6);
        });

        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int count = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                count = count + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoDao.selectById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(count);
        }
        return orderOutputAddReqList;

    }

    private String getQoo10Token(Long shopId) {
        StringBuilder url = new StringBuilder(GlobalConstants.QOO_BASE_URL);

        Map<String, String> keyParams = handlerKeyParam(shopId);
        url.append("?v=1.0&").append("&returnType=json&method=CertificationAPI.CreateCertificationKey");
        if (StringUtils.isNotBlank(keyParams.get("key"))) {
            url.append("&key=" + keyParams.get("key"));
        }
        if (StringUtils.isNotBlank(keyParams.get("id"))) {
            url.append("&user_id=" + keyParams.get("id"));
        }
        if (StringUtils.isNotBlank(keyParams.get("pwd"))) {
            url.append("&pwd=" + keyParams.get("pwd"));
        }
        JSONObject keyObject = null;
        try {
            String s = OkHttpUtils.okHttpRequestGet(url.toString());
            keyObject = JSONObject.parseObject(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (keyObject == null) {
            throw new BizException(SysConstant.Error_SecretKey_Expired_Sync);
        }
        String key = keyObject.getString("ResultObject");
        return key;
    }

    @Override
    public List<String> queryByShopIdAndNoUploadExpress(Long id, String currentDateFormat, String currentDateFormat1) {
        return dao.queryByShopIdAndNoUploadExpress(id, currentDateFormat, currentDateFormat1);
    }

    @Override
    public void updateOrderSendOut(String orderNo) {
        dao.updateOrderSendOut(orderNo);
    }

    @Override
    public void setSendingInfoByList(Map<Long, List<Qoo10RequestReq>> qoo10RequestReqs) {

        threadPoolTaskExecutor.execute(() -> {

            for (Long ashopid : qoo10RequestReqs.keySet()) {
                String key = getQoo10Token(ashopid);
                for (Qoo10RequestReq req : qoo10RequestReqs.get(ashopid)) {
                    StringBuilder url = new StringBuilder(GlobalConstants.QOO_BASE_URL);
                    url.append("?v=1.0&").append("&returnType=json&method=ShippingBasic.SetSendingInfo");
                    url.append("&key=" + key);
                    if (StringUtils.isNotBlank(req.getOrderNo())) {
                        url.append("&OrderNo=" + req.getOrderNo());
                    }
                    if (StringUtils.isNotBlank(req.getShippingCorp())) {
                        url.append("&ShippingCorp=" + req.getShippingCorp());
                    }
                    if (StringUtils.isNotBlank(req.getTrackingNo())) {
                        url.append("&TrackingNo=" + req.getTrackingNo());
                    }
                    JSONObject keyObject = null;
                    logger.info("Qoo10开始上传:" + url);
                    try {
                        String s = OkHttpUtils.okHttpRequestGet(url.toString());
                        keyObject = JSONObject.parseObject(s);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (keyObject == null) {
                        continue;
                    }
                    boolean resultCode = keyObject.getInteger("ResultCode") == 0;
                    if (resultCode) {
                        UpdateWrapper wrapper = new UpdateWrapper();
                        wrapper.eq("order_no", req.getOrderNo());
                        wrapper.set("is_upload_express", 1);
                        update(wrapper);
                    } else {
                        logger.info("Qoo10上传失败,原因" + keyObject.toJSONString());
                    }
                }
            }
        });
    }

    private Map handlerKeyParam(Long req) {
        ShopDo shopDo = shopDao.selectById(req);
        Map map = new HashMap();
        map.put("id", shopDo.getQootenId());
        map.put("key", shopDo.getQootenKey());
        map.put("pwd", shopDo.getQootenPwd());

        return map;
    }

    @Override
    public SingleResult sendOut(QooSendOutReq req, Long userId, Long companyId) {
        //校验余额是否不足
//        sufficientFundsCheck(companyId);
        List<String> failOrders = new ArrayList<>();
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        List<OrderQoo10Do> orderQoo10DoList = dao.selectBatchIds(req.getIds());
        Map<Integer, List<OrderQoo10Do>> collectMap = orderQoo10DoList.stream().filter(orderQoo10Do -> orderQoo10Do.getPackNo() != null).collect(Collectors.groupingBy(OrderQoo10Do::getPackNo));
        for (Map.Entry<Integer, List<OrderQoo10Do>> stringListEntry : collectMap.entrySet()) {
            Map<String, Object> result = sendOutOrder(stringListEntry, false, userId, companyId);
            if (result != null && result.get("orderOutputAddReq") != null) {
                orderOutputAddReqList.addAll((List) result.get("orderOutputAddReq"));
            }
            if (result != null && !CollectionUtils.isEmpty((List) result.get("failOrder"))) {
                failOrders.addAll((List) result.get("failOrder"));
            }
        }

        List<OrderQoo10Do> orderQoo10Dos = this.baseMapper.selectBatchIds(req.getIds());
        orderQoo10Dos.forEach(orderQoo10Do -> {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, orderQoo10Do.getId(), userId, 6);
        });

        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int count = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                count = count + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoDao.selectById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(count);
        }
        Map map = new HashMap();
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));


        return SingleResult.success(map);
    }

    @Override
    public SingleResult sendOutMatch(List<OrderOutputAddReq> orderOutputAddReqList, Long userId, Long companyId) {
        List<String> failOrders = outputService.addQoo10List(orderOutputAddReqList, userId);
        logger.info(JSONObject.toJSONString(failOrders));
        if (failOrders.size() > 0) {
            return SingleResult.failure("300", SysConstant.OrderYahoo_Export_Success, failOrders, orderOutputAddReqList.size() - failOrders.size());
        } else {
            return SingleResult.success(failOrders);
        }
    }

    @Override
    public void markSendOut(List<Long> ids, Long userId, Long companyId) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BizException(SysConstant.Pls_Choose_Order);
        }
        List<OrderQoo10Do> orderQoo10Dos = this.baseMapper.selectBatchIds(ids);
        orderQoo10Dos.forEach(orderQoo10Do -> {
            orderQoo10Do.setIsSendOut(1);
            dao.updateById(orderQoo10Do);
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_MARK_SEND, orderQoo10Do.getId(), userId, 2);

        });
    }
//
//    private void operateRecord(String str, OrderQoo10Do orderQoo10Do, Long userId) {
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setContent(str);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setType(6);
//        operateRecordDo.setThirdId(orderQoo10Do.getId());
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDao.insert(operateRecordDo);
//    }

    private OrderOutputPackageDo handlerOutputPackageDo(OrderOutputDo orderOutputDo, Long userId) {
        OrderOutputPackageDo orderOutputPackageDo = new OrderOutputPackageDo();
        orderOutputPackageDo.setWidth(0);
        orderOutputPackageDo.setWeight(0);
        orderOutputPackageDo.setLength(0);
        orderOutputPackageDo.setHeight(0);
        orderOutputPackageDo.setCreateTime(new Date());
        orderOutputPackageDo.setCreateBy(userId);
        orderOutputPackageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        orderOutputPackageDo.setOrderOutputId(orderOutputDo.getId());
        orderOutputPackageDao.insert(orderOutputPackageDo);

        return orderOutputPackageDo;
    }

    private OrderOutputDo handlerOutputDo(List<OrderQoo10Do> qoo10DoList, Long userId, Long companyId) {
        OrderOutputDo orderOutputDo = new OrderOutputDo();
        OrderQoo10Do orderQoo10Do = qoo10DoList.get(0);
        orderOutputDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        orderOutputDo.setCreateBy(userId);
        orderOutputDo.setCreateTime(new Date());
        orderOutputDo.setAddress(orderQoo10Do.getAddr1());
        orderOutputDo.setArea(orderQoo10Do.getAddr2());
        orderOutputDo.setTelPhone(orderQoo10Do.getBuyerTel());
        orderOutputDo.setTrackNumber(orderQoo10Do.getTrackingNo());
        orderOutputDo.setCompanyId(companyId);

        orderOutputDao.insert(orderOutputDo);
        orderOutputDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(orderOutputDo.getId()));
        orderOutputDao.updateById(orderOutputDo);

        return orderOutputDo;
    }

    private Map getParams(String key, String ShippingStat, String startDate, String endDate) {
        Map map = new LinkedHashMap();
        map.put("key", key);
        map.put("v", "1.0");
        map.put("returnType", "json");
        map.put("method", "ShippingBasic.GetShippingInfo_v2");
        map.put("ShippingStat", ShippingStat);
        map.put("search_Sdate", startDate);
        map.put("search_Edate", endDate);

        return map;
    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderQoo10Do entityDo, Long userId) {
//        entityDo.setCreateBy(userId);
//        entityDo.setCreateTime(new Date());
//        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderQoo10Do entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        OrderQoo10Do orderQoo10Do = this.baseMapper.selectById(id);
        return SingleResult.success(orderQoo10Do.getSystemMemo());
    }

    @Override
    public int update(QooUpdateReq req, Long userId) {
        OrderQoo10Do entityDo = dao.selectById(req.getId());
        entityDo.setSystemMemo(req.getSystemMemo());
        dao.updateById(entityDo);
        return dao.updateById(entityDo);
    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderQoo10Do entityDo, Long userId) {
//        entityDo.setUpdateBy(userId);
//        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(OrderQoo10Do entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        OrderQoo10Do entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderQoo10Do entityDo, Long userId) {
//        entityDo.setDeleteBy(userId);
//        entityDo.setDeleteTime(new Date());
    }

    @Override
    public QooDetailRes detail(Long id) {
        OrderQoo10Do entityDo = dao.selectById(id);
        QooDetailRes res = new QooDetailRes();
        BeanUtils.copyProperties(entityDo, res);
        res.setShippingStatus(shipStatus().get(entityDo.getShippingStatus()));

        ShopDo shopDo = shopDao.selectById(entityDo.getShopId());
        if (shopDo != null) {
            res.setShopName(shopDo.getShopName());
        }
        CompanyDo companyDo = companyDao.selectById(entityDo.getCompanyId());
        if (companyDo != null) {
            res.setCompanyCode(companyDo.getCompanyCode());
        }
        res.setIsSendOut(entityDo.getIsSendOut() == 1 ? "是" : "否");
        res.setIsUploadExpress(entityDo.getIsUploadExpress() == 1 ? "是" : "否");


        //日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(res.getId(), 6);
        res.setOperateResList(operateResList);
        return res;
    }

    //查询明细之后要执行的业务定制处理
    private Object handlerDetailAfter(Object res) {
        return res;
    }

    @Override
    public SingleResult pageInit(Long userId, Long companyId) {
        Map map = (Map) addInit(userId, companyId).getData();
        map.remove("shopList");
        map.remove("searchConditionList");
        return SingleResult.success(map);
    }

    @Override
    public List<QooListPageRes> getList(Map<String, String> map) {
        QueryWrapper<OrderQoo10Do> wrapper = queryBuild(map);
        List<OrderQoo10Do> list = this.list(wrapper);
        List<QooListPageRes> result = handlerListAfter(list);
        return result;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<OrderQoo10Do> wrapper = queryBuild(map);
        IPage<OrderQoo10Do> page = pageInit(map);
        page = this.page(page, wrapper);
        List<QooListPageRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }

    @Override
    public void exportExcel(Map<String, String> map, List<Long> ids, HttpServletResponse response) throws IOException {
        List<OrderQoo10Do> orderQoo10DoList = null;
        if (!CollectionUtils.isEmpty(ids)) {
            orderQoo10DoList = dao.selectBatchIds(ids);
        } else {
            QueryWrapper<OrderQoo10Do> wrapper = queryBuild(map);
            orderQoo10DoList = dao.selectList(wrapper);
        }

        List<QooExcelExportVo> excelExportVos = handlerQooDos(orderQoo10DoList);


        ExportParams exportParams = new ExportParams();
        exportParams.setCreateHeadRows(true);
        exportParams.setHeaderColor(IndexedColors.YELLOW.getIndex());
        ExcelUtils.exportExcel(excelExportVos, QooExcelExportVo.class, "Qoo10订单", exportParams, response);
    }

    private List<QooExcelExportVo> handlerQooDos(List<OrderQoo10Do> orderQoo10DoList) {
        List<QooExcelExportVo> excelExportVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderQoo10DoList)) {
            orderQoo10DoList.forEach(orderQoo10Do -> {
                QooExcelExportVo qooExcelExportVo = new QooExcelExportVo();
                BeanUtils.copyProperties(orderQoo10Do, qooExcelExportVo);
                qooExcelExportVo.setShippingStatus(shipStatus().get(orderQoo10Do.getShippingStatus()));
                qooExcelExportVo.setIsSendOut(orderQoo10Do.getIsSendOut() == 1 ? "是" : "否");
                qooExcelExportVo.setIsUploadExpress(orderQoo10Do.getIsUploadExpress() == 1 ? "是" : "否");
                excelExportVos.add(qooExcelExportVo);
            });
        }
        return excelExportVos;

    }

    private Map<String, String> shipStatus() {
        Map<String, String> map = new HashMap();
        map.put("1", "支払待ち");
        map.put("2", "支払済み");
        map.put("3", "配送確認");
        map.put("4", "配送中");
        map.put("5", "配送完了");
        return map;
    }

    //查询分页列表之后对列表数据的处理
    private List<QooListPageRes> handlerListAfter(List<OrderQoo10Do> list) {
        List<QooListPageRes> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(orderQoo10Do -> {
                QooListPageRes res = new QooListPageRes();
                BeanUtils.copyProperties(orderQoo10Do, res);
                res.setShippingStatus(shipStatus().get(orderQoo10Do.getShippingStatus()));

                ShopDo shopDo = shopDao.selectById(orderQoo10Do.getShopId());
                if (shopDo != null) {
                    res.setShopName(shopDo.getShopName());
                }
                CompanyDo companyDo = companyDao.selectById(orderQoo10Do.getCompanyId());
                if (companyDo != null) {
                    res.setCompanyCode(companyDo.getCompanyCode());
                }
                res.setIsSendOut(orderQoo10Do.getIsSendOut() == 1 ? "是" : "否");
                res.setIsUploadExpress(orderQoo10Do.getIsUploadExpress() == 1 ? "是" : "否");
                result.add(res);
            });
        }
        return result;
    }

    private IPage<OrderQoo10Do> pageInit(Map<String, String> map) {
        IPage<OrderQoo10Do> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderQoo10Do> queryBuild(Map<String, String> map) {
        QueryWrapper<OrderQoo10Do> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.and(i -> i.like("pack_no", map.get("keyword")).or().
                    like("order_no", map.get("keyword")).or()
                    .like("pack_no", map.get("keyword")).or()
                    .like("buyer_mobile", map.get("keyword")).or()
                    .like("buyer", map.get("keyword")).or()
                    .like("option_code", map.get("keyword")));
        }
        if (StringUtils.isNotBlank(map.get("startDate"))) {
            wrapper.ge("order_date", map.get("startDate"));
        }
        if (StringUtils.isNotBlank(map.get("endDate"))) {
            wrapper.lt("order_date", map.get("endDate"));
        }
        if (StringUtils.isNotBlank(map.get("companyId"))) {
            wrapper.eq("company_id", map.get("companyId"));
        }
        if (StringUtils.isNotBlank(map.get("ShippingStat"))) {
            wrapper.eq("shipping_status", map.get("ShippingStat"));
        }
        if (StringUtils.isNotBlank(map.get("isSendOut"))) {
            wrapper.eq("is_send_out", map.get("isSendOut"));
        }
        return wrapper;
    }


    private Map<String, Object> sendOutOrder(Map.Entry<Integer, List<OrderQoo10Do>> entry, boolean b, Long userId, Long companyId) {
        Map<String, Object> result = new HashMap<>();

        List<String> failOrder = new ArrayList<>();
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        OrderOutputAddReq orderOutputAddReq = new OrderOutputAddReq();
        orderOutputAddReq.setPlatform("qoo10");
        orderOutputAddReq.setPlatformNumber(entry.getValue().get(0).getOrderNo().toString());
        orderOutputAddReq.setOrderType(1);
        orderOutputAddReq.setSendDate(new Date());
        orderOutputAddReq.setShopId(entry.getValue().get(0).getShopId());
        orderOutputAddReq.setCompanyId(entry.getValue().get(0).getCompanyId());
        orderOutputAddReq.setOrderNo(entry.getValue().get(0).getOrderNo().toString());
        if (StringUtils.isNotBlank(entry.getValue().get(0).getOptionCode()))
            orderOutputAddReq.setSku(entry.getValue().get(0).getOptionCode());
        else
            orderOutputAddReq.setSku(entry.getValue().get(0).getSellerItemCode());
        if (entry.getValue().get(0).getDeliveredDate() != null) {
            orderOutputAddReq.setDeliveryDate(entry.getValue().get(0).getDeliveredDate().toString());
        }
        orderOutputAddReq.setReceiverName(entry.getValue().get(0).getReceiver());
        if (StringUtils.isNotBlank(entry.getValue().get(0).getReceiverTel()) && !entry.getValue().get(0).getReceiverTel().equals("+81--")) {
            orderOutputAddReq.setTelPhone(entry.getValue().get(0).getReceiverTel().replaceAll("\\+81-", ""));
        } else if (StringUtils.isNotBlank(entry.getValue().get(0).getReceiverMobile()) && !entry.getValue().get(0).getReceiverMobile().equals("+81--")) {
            orderOutputAddReq.setTelPhone(entry.getValue().get(0).getReceiverMobile().replaceAll("\\+81-", ""));
        }

        if (entry.getValue().get(0).getZipCode() != null) {
            orderOutputAddReq.setPostCode(entry.getValue().get(0).getZipCode().toString());
        }
//        orderOutputAddReq.setArea();
        orderOutputAddReq.setAddress(entry.getValue().get(0).getAddr1() + entry.getValue().get(0).getAddr2());

        List<OrderOutputProductAddReq> productAddList = new ArrayList<>();

        Map<String, Integer> skuMap = new HashMap(); //key--sku,value--count
        StringBuilder orderNoBuilder = new StringBuilder();
        //默认仓库捆包发货
        for (OrderQoo10Do orderQoo10Do : entry.getValue()) {
            String sku = "";
            if (StringUtils.isNotBlank(orderQoo10Do.getOptionCode())) {
                sku = orderQoo10Do.getOptionCode();
            } else {
                sku = orderQoo10Do.getSellerItemCode();
            }
            String[] split = sku.split(",");
            if (split.length > 0) {
                for (String s : split) {
                    if (skuMap.get(s) != null) {
                        skuMap.put(s, skuMap.get(s) + orderQoo10Do.getOrderQty());
                    } else {
                        skuMap.put(s, orderQoo10Do.getOrderQty());
                    }
                }
            }
        }
//        orderOutputAddReq.setOrderNoTips(orderNoBuilder.toString());

        Long storageId = 0L;
        List<Map.Entry<String, Integer>> failedSkuList = new ArrayList<>();
        //优先仓库
        Long stateId = mRegionService.getStateIdByPostCode(entry.getValue().get(0).getZipCode());
        if (stateId <= 8) {//大阪地区优先发货仓库
            storageId = 9L;
        } else {//东京仓库优先发货仓库
            storageId = 10L;
        }
        for (Map.Entry<String, Integer> stringIntegerEntry : skuMap.entrySet()) {
            LambdaQueryWrapper<ProductInfoDo> productInfoDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productInfoDoLambdaQueryWrapper.eq(ProductInfoDo::getCommoditySku, stringIntegerEntry.getKey())
                    .eq(ProductInfoDo::getCompanyId, companyId);
            ProductInfoDo productInfoDo = productInfoDao.selectOne(productInfoDoLambdaQueryWrapper);
            if (productInfoDo == null) {
                LambdaQueryWrapper<ProductSkuMapDo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ProductSkuMapDo::getSubSku, stringIntegerEntry.getKey())
                        .eq(ProductSkuMapDo::getCompanyId, companyId);
                ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(wrapper);
                if (productSkuMapDo != null) {
                    productInfoDo = productInfoDao.selectById(productSkuMapDo.getProductInfoId());
                }
            }
            if (productInfoDo == null) {
                failOrder.add("没有该商品：" + stringIntegerEntry.getKey());
                result.put("failOrder", failOrder);
                return result;
            }
            LambdaQueryWrapper<StockRecordDo> stockRecordDoLambdaQueryWrapper = new LambdaQueryWrapper();
            stockRecordDoLambdaQueryWrapper.eq(StockRecordDo::getShopId, entry.getValue().get(0).getShopId())
                    .eq(StockRecordDo::getProductInfoId, productInfoDo.getId())
                    .eq(StockRecordDo::getStorageId, storageId);

            StockRecordDo stockRecordDo = stockRecordDao.selectOne(stockRecordDoLambdaQueryWrapper);
            int count = stockRecordDao.getOrderOutCount(productInfoDo.getId(), entry.getValue().get(0).getShopId(), storageId);
            if (!(stockRecordDo != null && stockRecordDo.getCanSellCount() - count >= stringIntegerEntry.getValue())) {
                failedSkuList.add(stringIntegerEntry);
                continue;
            }

            OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
            productDetail.setProductId(productInfoDo.getId());
            productDetail.setCount(stringIntegerEntry.getValue());
            productAddList.add(productDetail);
        }
        //捆包信息
        OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();

        List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
        packageDetail.setProductList(productAddList);
        packageAddReqList.add(packageDetail);
        orderOutputAddReq.setStorageId(storageId);
        orderOutputAddReq.setPackageList(packageAddReqList);
        if (failedSkuList.size() != skuMap.size()) {
            orderOutputAddReqList.add(orderOutputAddReq);
        }
        List<Map.Entry<String, Integer>> failedSkuList2 = new ArrayList<>();
        //判断失败SKU信息，默认仓库无库存
        if (failedSkuList.size() > 0) {
            //查找第二个捆包仓库
            LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper();
            lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1).ne(StorageDo::getId, storageId);
            List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
            storageId = storageDos.get(0).getId();


            for (Map.Entry<String, Integer> stringIntegerEntry : failedSkuList) {
                ProductInfoDo productInfoDo = productInfoService.getProductDo(stringIntegerEntry.getKey(), companyId);
                if (productInfoDo == null) {
                    failOrder.add("没有该商品：" + stringIntegerEntry.getKey());
                    result.put("failOrder", failOrder);
                    return result;
                }

                LambdaQueryWrapper<StockRecordDo> stockRecordDoLambdaQueryWrapper = new LambdaQueryWrapper();
                stockRecordDoLambdaQueryWrapper.eq(StockRecordDo::getShopId, entry.getValue().get(0).getShopId())
                        .eq(StockRecordDo::getProductInfoId, productInfoDo.getId())
                        .eq(StockRecordDo::getStorageId, storageId);

                StockRecordDo stockRecordDo = stockRecordDao.selectOne(stockRecordDoLambdaQueryWrapper);
                int count = stockRecordDao.getOrderOutCount(productInfoDo.getId(), entry.getValue().get(0).getShopId(), storageId);
                double[] size = new double[4];
                Double shipPirce = 99999d;
                if (!(stockRecordDo != null && stockRecordDo.getCanSellCount() - count >= stringIntegerEntry.getValue())) {
                    failedSkuList2.add(stringIntegerEntry);
                    continue;
                }

                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                productDetail.setProductId(productInfoDo.getId());
                productDetail.setCount(stringIntegerEntry.getValue());
                productAddList.add(productDetail);
            }
            //捆包信息
            packageDetail = new OrderOutputPackageAddReq();

            packageAddReqList = new ArrayList<>();
            packageDetail.setProductList(productAddList);
            packageAddReqList.add(packageDetail);
            OrderOutputAddReq addReq = new OrderOutputAddReq();
            BeanUtils.copyProperties(orderOutputAddReq, addReq);
            addReq.setStorageId(storageId);
            addReq.setPackageList(packageAddReqList);
            if (failedSkuList2.size() != failedSkuList.size()) {
                orderOutputAddReqList.add(addReq);
            }
        }
        if (failedSkuList2.size() > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Map.Entry<String, Integer> stringIntegerEntry : failedSkuList2) {
                storageId = 0L;
                ProductInfoDo productInfoDo = productInfoService.getProductDo(stringIntegerEntry.getKey(), companyId);
                if (productInfoDo == null) {
                    failOrder.add("没有该商品：" + stringIntegerEntry.getKey());
                    result.put("failOrder", failOrder);
                    return result;
                }
                LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper();
                queryWrapper.eq(StorageDo::getCountryType, 1);
                List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                storageId = 0L;
                long productId = productInfoDo.getId();
                double shipPirce = 99999D;
                for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                    LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                    double[] size = shipPriceService.countSameSkuSize(new double[4], productId,
                            1);
                    wrapper2.eq(StockRecordDo::getShopId, entry.getValue().get(0).getShopId())
                            .eq(StockRecordDo::getProductInfoId, productId)
                            .eq(StockRecordDo::getStorageId, storageDo.getId());
                    StockRecordDo stockRecordDo1 = stockRecordDao.selectOne(wrapper2);
                    int noDeliveredCount1 = stockRecordDao.getOrderOutCount(productId, entry.getValue().get(0).getShopId(), storageDo.getId())
                            + stockRecordDao.getOrderOutTurn2FbaCount(productId, entry.getValue().get(0).getShopId(), storageDo.getId());
                    if (stockRecordDo1 != null && stockRecordDo1.getCanSellCount() - noDeliveredCount1 >= stringIntegerEntry.getValue()) {
                        List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(entry.getValue().get(0).getZipCode(),
                                size[3], size[0] + size[1] + size[2], size[0], size[1], size[2], entry.getValue().get(0).getCodPrice().intValue(),
                                0, storageDo.getId(), 1);
                        if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                        if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                            shipPirce = shipPriceDos.get(0).getPrice();
                            storageId = storageDo.getId();
                        }
                    }
                }
                if (storageId != 0) {
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setProductId(productInfoDo.getId());
                    productDetail.setCount(stringIntegerEntry.getValue());
                    productAddList = new ArrayList<>();
                    productAddList.add(productDetail);

                    packageDetail = new OrderOutputPackageAddReq();
                    packageAddReqList = new ArrayList<>();
                    packageDetail.setProductList(productAddList);
                    OrderOutputAddReq addReq = new OrderOutputAddReq();
                    BeanUtils.copyProperties(orderOutputAddReq, addReq);
                    packageAddReqList.add(packageDetail);
                    addReq.setStorageId(storageId);
                    addReq.setPackageList(packageAddReqList);
                    orderOutputAddReqList.add(addReq);
                } else {
                    stringBuilder.append("(" + stringIntegerEntry.getKey() + ")");
                }
            }
            if (stringBuilder.length() > 0) {
                failOrder.add("(" + stringBuilder.toString() + "库存不足)");
            }
        }
        if (failOrder.size() > 0) orderOutputAddReqList.clear();
        result.put("orderOutputAddReq", orderOutputAddReqList);
        result.put("failOrder", failOrder);

        return result;
    }

}
